package dao

import (
	"context"
	"errors"
	"github.com/go-sql-driver/mysql"
	"gorm.io/gorm"
	"time"
)

var (
	ErrUserDuplicateEmail = errors.New("邮箱冲突")
	ErrUserNotFound       = gorm.ErrRecordNotFound
)

type UserDAO struct {
	db *gorm.DB
}

func NewUserDAO(db *gorm.DB) *UserDAO {
	return &UserDAO{
		db: db,
	}
}
func (dao *UserDAO) Insert(ctx context.Context, u User) error {
	// 存毫秒数
	now := time.Now().UnixNano()
	u.Ctime = now
	u.Utime = now
	err := dao.db.WithContext(ctx).Create(&u).Error
	// 类型断言,判断是否是mysql的唯一冲突错误
	if mysqlErr, ok := err.(*mysql.MySQLError); ok {
		const uniqueConflictsErrNo uint16 = 1062
		if mysqlErr.Number == uniqueConflictsErrNo {
			// 邮箱已存在
			return ErrUserDuplicateEmail
		}
	}
	return err
}
func (dao *UserDAO) Update(ctx context.Context, u User, Id int64, updatedUser map[string]interface{}) error {
	u.Utime = time.Now().UnixNano()
	// 使用 Updates 方法，显式指定要更新的字段
	return dao.db.WithContext(ctx).Model(&User{}).Where("id = ?", Id).Updates(updatedUser).Error
}
func (dao *UserDAO) FindByEmail(ctx context.Context, email string) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("email = ?", email).First(&u).Error
	return u, err
}
func (dao *UserDAO) FindById(ctx context.Context, Id int64) (User, error) {
	var u User
	err := dao.db.WithContext(ctx).Where("id = ?", Id).First(&u).Error
	return u, err
}

// User 直接对应数据库中的表
// 有些人叫做entity，有些人叫做model
type User struct {
	Id int64 `gorm:"primaryKey,autoIncrement"`
	// 全部用户邮箱唯一
	Email        string `gorm:"unique"`
	Password     string
	Nickname     string `gorm:"size:10"` // 用户昵称
	Birthday     string `gorm:"size:10"` // 生日
	Introduction string `gorm:"size:50"` // 个人介绍
	// 创建时间,毫秒数，解决时区问题
	Ctime int64
	// 更新时间
	Utime int64
}
